﻿using System;
using System.Collections.Generic;
using System.Text;
using Widgetsphere.Generator.Models;
using Widgetsphere.Generator.Common.Util;
using System.Collections;
using System.Collections.ObjectModel;
using Widgetsphere.Generator.ProjectItemGenerators;
using Widgetsphere.Generator.DataTransfer;

namespace Acme.GeneratorExtension.GenerateToDataTransfer
{
	/// <summary>
	/// This template will generate the content for the[EntityName]MetaData.generated.cs file. 
	/// This file contains a public partial class [EntityName]MetaData. The file will contain
	/// the core implementation of the [EntityName]MetaData. It will be overwritten each time
	/// a generation occurs. It should not be extended by programmers.
	/// </summary>
	public class MetaDataInfoClassTemplate : BaseDataTransferTemplate
	{
		#region Class Members
		private StringBuilder sb = new StringBuilder();
		private Table _currentTable;
		#endregion

		#region Constructors
		public MetaDataInfoClassTemplate(ModelRoot model, Table currentTable)
		{
			_model = model;
			_currentTable = currentTable;
		}
		#endregion

		#region BaseClassTemplate overrides
		/// <summary>
		/// Returns the name of the file. That is to be added to the project
		/// </summary>
		public override string FileName
		{
			get { return string.Format("{0}MetaData.Generated.cs", _currentTable.PascalName); }
		}

		/// <summary>
		/// Returns the a parent item name. This is only necessary when the 
		/// parent item is another file in the project
		/// </summary>
		public string ParentItemName
		{
			get { return string.Format("{0}MetaData.cs", _currentTable.PascalName); }
		}

		/// <summary>
		/// Returns the generated contents of the file as a string
		/// </summary>
		public override string FileContent
		{
			get
			{
				GenerateContent();
				return sb.ToString();
			}
		}

		#endregion

		#region GenerateContent

		private void GenerateContent()
		{
			try
			{
				this.AppendUsingStatements();
				sb.AppendLine("namespace " + DefaultNamespace + ".MetaData");
				sb.AppendLine("{");
				this.AppendClass();
				sb.AppendLine("}");
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		#endregion

		#region namespace / objects

		public void AppendUsingStatements()
		{
			sb.AppendLine("using System;");
			sb.AppendLine("using System.Collections.Generic;");
			sb.AppendLine();
		}

		private void AppendClass()
		{			
			sb.AppendLine("	/// <summary>");

			//Use the description if one exists
			if (_currentTable.Description == "")
				sb.AppendLine("	/// " + _currentTable.Description);
			else
				sb.AppendLine("	/// This class maps to the database table '" + _currentTable.Name + "'.");

			sb.AppendLine("	/// </summary>");
			sb.AppendLine("	public partial class " + _currentTable.PascalName + "MetaData");
			sb.AppendLine("	{");
			this.AppendGetFieldCamelNames();
			this.AppendProperties();
			sb.AppendLine("	}");
			sb.AppendLine();
		}

		//Create a method to return all database names for this object.
		private void AppendGetFieldCamelNames()
		{
			sb.AppendLine("		#region Methods");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// This method returns the database names of all fields");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <returns></returns>");
			sb.AppendLine("		public static List<string> GetFieldCamelNames()");
			sb.AppendLine("		{");
			sb.AppendLine("			List<string> retval = new List<string>();");
			foreach (Column column in _currentTable.GeneratedColumns)
			{
				sb.AppendLine("			retval.Add(\"" + column.CamelName + "\");");
			}
			sb.AppendLine("			return retval;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		//Loop through and create properties for each object
		private void AppendProperties()
		{
			sb.AppendLine("		#region Properties");
			sb.AppendLine();
			foreach (Column column in _currentTable.GeneratedColumns)
			{
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// This is the " + column.PascalName + " property");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		/// <returns></returns>");
				sb.AppendLine("		public " + column.GetCodeType(true) + " " + column.PascalName + ";");
				sb.AppendLine();
			}			
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}
		#endregion

	}
}